import EchartsComponent, { MyChartOption } from '@/components/EchartsComponent';
import HandleBtn from '@/components/HandleBar/btn';
import { ProForm, ProFormDatePicker, type ProColumns } from '@/components/Pro';
import { getEmptyOptions } from '@/dictionary';
import SelectedTags from '@/pages/SiteMonitor/HisCurve/components/SelectedTags';
import SwitchButtons from '@/pages/SiteMonitor/HisCurve/components/SwitchButtons';
import {
  historyCurveControllerMetadata,
  historyCurveControllerMetadataExport,
  historyCurveControllerMetadataList,
} from '@/services/ess/historicalCurve';
import { downloadFetch } from '@/utils/downloadFile';
import { DownloadOutlined } from '@ant-design/icons';
import ProTable from '@ant-design/pro-table';
import { useIntl } from '@umijs/max';
import { Button, message, Spin } from 'antd';
import dayjs from 'dayjs';
import React, { useRef, useState } from 'react';

type IProps = {
  tagList: string[];
  reset: () => void;
};

interface viewTagInter extends API.DataColumnDTO {
  uniqueId?: string;
}

interface rawTableColumnType {
  deviceName: string | undefined;
  title: string | undefined;
  maxValue: Record<string, any>[];
  maxTime: string | undefined;
  minValue: Record<string, any>[];
  minTime: string | undefined;
}

const RawData: React.FC<IProps> = (props) => {
  const { tagList, reset } = props;
  const intl = useIntl();
  const chartRef = useRef(null);
  const tableRef = useRef(null);
  const [selectDate, setSelectDate] = useState(dayjs());
  const [currentTags, setCurrentTags] = useState<viewTagInter[]>();
  const [type, setType] = useState('chart');
  const [chartOptions, setChartOptions] = useState<MyChartOption>(getEmptyOptions());
  const [loading, setLoading] = useState(false);
  const [rawData, setRawData] = useState();
  const submitCloseTags = (tags: viewTagInter[]) => {
    setCurrentTags(tags);
  };
  const getNullTitle = (val: string | null) => {
    if (val === null) {
      return '';
    } else {
      return val + '_';
    }
  };
  const getDataIndex = (item: API.DataColumnDTO): string | undefined => {
    switch (item.nodeType) {
      case 'ROOT':
        return item.dataAttr;
      case 'AREA':
        return `${item.areaId ? item.areaId + '_' : ''}${item.dataAttr}`;
      case 'DEVICE_GROUP':
        return `${item.areaId ? item.areaId + '_' : ''}${
          item.deviceType ? item.deviceType + '_' : ''
        }${item.dataAttr}`;
      case 'DEVICE':
        return `${item.areaId ? item.areaId + '_' : ''}${
          item.deviceCode ? item.deviceCode + '_' : ''
        }${item.dataAttr}`;
      default:
        return '';
    }
  };
  const getElseColumns = (tableData: API.DataColumnDTO[]): ProColumns[] => {
    return tableData?.map((item: API.DataColumnDTO) => {
      return {
        title: `${getNullTitle(item.areaName)}${getNullTitle(item.deviceName)}${
          item.dataName || ''
        }${item.unit ? `(${item.unit})` : ''}`,
        dataIndex: getDataIndex(item),
        width: 150,
      };
    });
  };
  const formatterOptions = (data: API.DataCurveDTO): MyChartOption => {
    const seriesData = data.yaxis.map((item) => {
      return {
        yAxisIndex: item.unit === '%' ? 1 : 0,
        type: 'line',
        data: item.pointsValues,
        name: item.title + '' + (item.unit ? `(${item.unit})` : ''),
        showSymbol: false,
        smooth: true,
      };
    });
    const hasSOC = data.yaxis.some((item) => item.unit === '%');

    return {
      grid: {
        top: '35%',
      },
      dataZoom: {
        type: 'inside',
      },
      xAxis: {
        axisTick: {
          inside: true,
        },
        data: data?.xaxis,
      },
      yAxis: [
        {
          type: 'value',
          name: '',
          axisLine: {
            show: true,
          },
        },
        {
          type: 'value',
          name: '%',
          show: hasSOC,
          axisLine: {
            show: true,
          },
        },
      ],
      legend: {},
      tooltip: {
        trigger: 'axis',
      },
      series: seriesData,
    };
  };
  const getRawData = (data: API.DataCurveDTO): rawTableColumnType[] | undefined => {
    return data?.yaxis?.map((item) => {
      return {
        deviceName: item.deviceName,
        dataItemName: item.dataItemName + '' + (item.unit ? `(${item.unit})` : ''),
        maxValue: item.maxValue,
        maxTime: item.maxTime,
        minValue: item.minValue,
        minTime: item.minTime,
        avgValue: item.avgValue,
      };
    });
  };
  const rawChartColumns: ProColumns[] = [
    {
      title: intl.formatMessage({ id: 'hisCurve.no' }),
      valueType: 'index',
      dataIndex: 'id',
      width: 80,
    },
    {
      title: intl.formatMessage({ id: 'hisCurve.deviceName' }),
      dataIndex: 'deviceName',
      width: 120,
    },
    {
      title: intl.formatMessage({ id: 'hisCurve.dataItem' }),
      dataIndex: 'dataItemName',
      width: 120,
    },
    {
      title: intl.formatMessage({ id: 'hisCurve.maxV' }),
      dataIndex: 'maxValue',
      width: 120,
    },
    {
      title: intl.formatMessage({ id: 'hisCurve.maxVT' }),
      dataIndex: 'maxTime',
      width: 200,
    },
    {
      title: intl.formatMessage({ id: 'hisCurve.minV' }),
      dataIndex: 'minValue',
      width: 120,
    },
    {
      title: intl.formatMessage({ id: 'hisCurve.minVT' }),
      dataIndex: 'minTime',
      width: 200,
    },
    {
      title: intl.formatMessage({ id: 'hisCurve.avgT' }),
      dataIndex: 'avgValue',
      width: 120,
    },
  ];
  const baseColumns: ProColumns[] = [
    {
      title: intl.formatMessage({ id: 'hisCurve.no' }),
      valueType: 'index',
      dataIndex: 'id',
      width: 80,
    },
    {
      title: intl.formatMessage({ id: 'hisCurve.timeSelect' }),
      dataIndex: 'date',
      width: 150,
    },
  ];
  const exportIncomeReport = () => {
    const params = {
      date: dayjs(selectDate).format('YYYY-MM-DD'),
      columnList: currentTags,
    };
    downloadFetch(historyCurveControllerMetadataExport, params);
  };
  const [elseColumns, setElseColumns] = useState([]);
  const getColumns = baseColumns.concat(elseColumns);
  const exportChart = () => {
    const chart = chartRef?.current?.instance();
    if (chart) {
      const svgUrl = chart.getDataURL({
        type: 'svg',
        pixelRatio: 2,
        backgroundColor: '#fff',
      });

      const img = new Image();
      img.src = svgUrl;
      img.onload = () => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');

        canvas.width = chart.getWidth();
        canvas.height = chart.getHeight();

        if (ctx) {
          ctx.fillStyle = '#fff';
          ctx.fillRect(0, 0, canvas.width, canvas.height);

          ctx.drawImage(img, 0, 0);
        }

        const pngUrl = canvas.toDataURL('image/png');
        const link = document.createElement('a');
        link.download = `${intl.formatMessage({
          id: 'statistics.analyze.historyCurveData',
        })}_${dayjs().format('YYYY-MM-DD_HH:mm:ss')}.png`;
        link.href = pngUrl;
        link.click();
      };
    }
  };
  const handleSearch = () => {
    const params = {
      date: dayjs(selectDate).format('YYYY-MM-DD'),
      columnList: currentTags,
    };
    if (!params?.columnList.length) {
      message.warning(intl.formatMessage({ id: 'global.leastOne' }));
      return false;
    }
    if (type === 'chart') {
      setLoading(true);
      historyCurveControllerMetadata(params).then((res) => {
        if (res.success) {
          chartRef?.current?.instance().clear();
          setChartOptions(formatterOptions(res.data));
          setRawData(getRawData(res.data));
          setLoading(false);
        } else {
          setChartOptions(getEmptyOptions());
          setLoading(false);
        }
      });
    } else {
      tableRef?.current?.reload();
    }
  };
  return (
    <>
      <div>
        <ProForm
          layout={'inline'}
          submitter={false}
          params={{
            type: type,
            selectDate: selectDate,
          }}
          onFinish={handleSearch}
        >
          <ProFormDatePicker
            name={'date'}
            initialValue={dayjs()}
            fieldProps={{
              allowClear: false,
              value: selectDate,
              disabledDate: (current) => {
                return current && current > dayjs().endOf('day');
              },
              onChange: (dateVal) => {
                setSelectDate(dateVal);
              },
            }}
            label={intl.formatMessage({ id: 'hisCurve.timeSelect' })}
          ></ProFormDatePicker>
          <ProForm.Item>
            <Button type={'primary'} htmlType={'submit'}>
              {intl.formatMessage({ id: 'global.search' })}
            </Button>
          </ProForm.Item>
          <ProForm.Item>
            <Button
              onClick={() => {
                setSelectDate(dayjs());
                reset();
                if (type === 'chart') {
                  chartRef?.current?.instance().clear();
                  setChartOptions(getEmptyOptions());
                  setRawData([]);
                } else {
                  tableRef?.current?.reload();
                }
              }}
            >
              {intl.formatMessage({ id: 'global.reset' })}
            </Button>
          </ProForm.Item>
        </ProForm>
        <SelectedTags tagList={tagList} submitCloseTags={submitCloseTags}></SelectedTags>
        <div style={{ marginTop: 20 }}>
          <SwitchButtons
            changeButtons={(value: string) => {
              setType(value);
              setTimeout(() => {
                const params = {
                  date: dayjs(selectDate).format('YYYY-MM-DD'),
                  columnList: currentTags,
                };
                if (!params?.columnList?.length) {
                  message.warning(intl.formatMessage({ id: 'global.leastOne' }));
                  return false;
                }
                if (value === 'chart') {
                  setLoading(true);
                  historyCurveControllerMetadata(params).then((res) => {
                    if (res.success) {
                      chartRef?.current?.instance().clear();
                      setChartOptions(formatterOptions(res.data));
                      setRawData(getRawData(res.data));
                      setLoading(false);
                    } else {
                      setChartOptions(getEmptyOptions());
                      setLoading(false);
                    }
                  });
                } else {
                  tableRef?.current?.reload();
                }
              }, 0);
            }}
          ></SwitchButtons>
        </div>
        {type === 'chart' ? (
          <div style={{ marginTop: 20 }}>
            <Spin spinning={loading}>
              <div style={{ position: 'relative' }}>
                <Button
                  icon={<DownloadOutlined />}
                  onClick={exportChart}
                  style={{ position: 'absolute', right: 0, top: -40 }}
                >
                  {intl.formatMessage({ id: 'statistics.analyze.exportImage' })}
                </Button>
                <EchartsComponent
                  option={chartOptions}
                  height={400}
                  ref={chartRef}
                ></EchartsComponent>
              </div>
            </Spin>
            <div>
              <ProTable
                scroll={{ y: 240 }}
                toolBarRender={false}
                loading={loading}
                columns={rawChartColumns}
                dataSource={rawData}
                search={false}
                pagination={false}
              ></ProTable>
            </div>
          </div>
        ) : (
          <div style={{ marginTop: 20 }}>
            <ProTable
              scroll={{ y: 300 }}
              actionRef={tableRef}
              search={false}
              params={{
                type: type,
                date: selectDate,
              }}
              toolBarRender={() => {
                return (
                  <HandleBtn
                    key="export"
                    handleType="export"
                    onClick={() => {
                      exportIncomeReport();
                    }}
                  >
                    {intl.formatMessage({ id: 'statistics.common.export' })}
                  </HandleBtn>
                );
              }}
              columns={getColumns}
              request={async (values) => {
                if (values.type === 'list') {
                  const params = {
                    date: dayjs(values.date).format('YYYY-MM-DD'),
                    columnList: currentTags,
                  };
                  if (!params?.columnList.length) {
                    message.warning(intl.formatMessage({ id: 'global.leastOne' }));
                    return false;
                  }
                  const res = await historyCurveControllerMetadataList(params);
                  if (res.success) {
                    setElseColumns(getElseColumns(res?.data?.dataColumnList));
                    return {
                      success: res.success,
                      data: res?.data?.dataList,
                    };
                  }
                }
              }}
            ></ProTable>
          </div>
        )}
      </div>
    </>
  );
};
export default RawData;
